//
// Created by YE on 2024/2/13.
//
#include "ych_string.h"
#include "ych_exception.h"

void initString(YString *string) {
    string->data = malloc(INITIAL_CAPACITY * sizeof(char));
    if (string->data == NULL) {
        throw(EXCEPTION_MEMORY);
    }
    *string->data = '\0';
    string->length = 0;
    string->capacity = INITIAL_CAPACITY;
}

void copyString(YString *string, const char *copied) {
    string->length = strlen(copied);
    string->capacity = string->length + 1;
    string->data = malloc((string->capacity) * sizeof(char));
    if (string->data == NULL) {
        throw(EXCEPTION_MEMORY);
    }
    strcpy(string->data, copied);
}

void copyYString(YString *string, YString *copied) {
    string->length = copied->length;
    string->capacity = string->length + 1;
    string->data = malloc((string->capacity) * sizeof(char));
    if (string->data == NULL) {
        throw(EXCEPTION_MEMORY);
    }
    strcpy(string->data, copied->data);
}

void cutString(YString *string, const char *cut, size_t pos, size_t length) {
    string->data = malloc((length + 1) * sizeof(char));
    if (string->data == NULL) {
        throw(EXCEPTION_MEMORY);
    }
    strncpy(string->data, cut + pos, length);
    *(string->data + length) = '\0';
    string->length = length;
    string->capacity = length + 1;
}

void appendString(YString *string, const char *append) {
    size_t appendLen = strlen(append);
    size_t requiredCapacity = string->length + appendLen + 1;

    if (requiredCapacity >string->capacity) {
        while (requiredCapacity > string->capacity)
            string->capacity <<= 1;
        string->data = realloc(string->data, string->capacity * sizeof(char));
        if (string->data == NULL) {
            throw(EXCEPTION_MEMORY);
        }
    }
    strcat(string->data, append);
    string->length += appendLen;
}

void appendChar(YString *string, char append) {
    size_t requiredCapacity = string->length + 1;

    if (requiredCapacity >= string->capacity) {
        while (requiredCapacity >= string->capacity)
            string->capacity <<= 1;
        string->data = realloc(string->data, string->capacity * sizeof(char));
        if (string->data == NULL) {
            throw(EXCEPTION_MEMORY);
        }
    }
    string->data[string->length] = append;
    string->data[string->length + 1] = '\0';
    string->length += 1;
}

void appendYString(YString *string, YString *append) {
    size_t requiredCapacity = string->length + append->length + 1;
    if (requiredCapacity > string->capacity) {
        while (requiredCapacity > string->capacity)
            string->capacity <<= 1;
        string->data = realloc(string->data, string->capacity * sizeof(char));
        if (string->data == NULL) {
            throw(EXCEPTION_MEMORY);
        }
    }
    strcat(string->data, append->data);
    string->length += append->length;
}

void freeYString(YString *string) {
    free(string->data);
    string->data = NULL;
    string->length = 0;
    string->capacity = 0;
}

void deleteYString(YString *string) {
    free(string->data);
    free(string);
}

int compareYString(YString *string1, YString *string2) {
    return strcmp(string1->data, string2->data) == 0;
}